using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace XnaDevRu.BulletX
{
	/// <summary>
	/// btSphereShape implements an implicit (getSupportingVertex) Sphere
	/// </summary>
	public class SphereShape : ConvexShape
	{
		public SphereShape(float radius)
			: base()
		{
			Vector3 temp = ImplicitShapeDimensions;
			temp.X = radius;
			ImplicitShapeDimensions = temp;
		}

		public float Radius { get { return ImplicitShapeDimensions.X; } }

		public override BroadphaseNativeTypes ShapeType
		{
			get
			{
				return BroadphaseNativeTypes.Sphere;
			}
		}

		public override string Name
		{
			get
			{
				return "Sphere";
			}
		}

		public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
		{
			return new Vector3();
		}

		/// <summary>
		/// to improve gjk behaviour, use radius+margin as the full margin, so never get into the penetration case
		/// this means, non-uniform scaling is not supported anymore
		/// </summary>
		public override float Margin
		{
			get
			{
				return LocalScaling.X * Radius + base.Margin;
			}
			set
			{
				base.Margin = value;
			}
		}

		public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
		{
			if (supportVerticesOut != null)
				for (int i = 0; i < supportVerticesOut.Length; i++)
					supportVerticesOut[i] = new Vector3();
		}

		public override void CalculateLocalInertia(float mass, out Vector3 inertia)
		{
			float elem = 0.4f * mass * Margin * Margin;
			inertia = new Vector3(elem, elem, elem);
		}

		public override Vector3 LocalGetSupportingVertex(Vector3 vec)
		{
			Vector3 supVertex = LocalGetSupportingVertexWithoutMargin(vec);

			Vector3 vecnorm = vec;
			if (vecnorm.LengthSquared() < (MathHelper.Epsilon * MathHelper.Epsilon))
			{
				vecnorm = new Vector3(-1f, -1f, -1f);
			}
			vecnorm.Normalize();
			supVertex += Margin * vecnorm;
			return supVertex;
		}

		public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
		{
			Vector3 center = t.Translation;
			Vector3 extent = new Vector3(Margin, Margin, Margin);
			aabbMin = center - extent;
			aabbMax = center + extent;
		}
	}
}
